home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmigaPlus / Tools / Development / stunnel-4.04 / _src / src / sthreads.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-12-28  |  5.5 KB  |  208 lines

  1. /*
  2.  *   stunnel       Universal SSL tunnel
  3.  *   Copyright (c) 1998-2002 Michal Trojnara <Michal.Trojnara@mirt.net>
  4.  *                 All Rights Reserved
  5.  *
  6.  *   This program is free software; you can redistribute it and/or modify
  7.  *   it under the terms of the GNU General Public License as published by
  8.  *   the Free Software Foundation; either version 2 of the License, or
  9.  *   (at your option) any later version.
  10.  *
  11.  *   This program is distributed in the hope that it will be useful,
  12.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *   GNU General Public License for more details.
  15.  *
  16.  *   You should have received a copy of the GNU General Public License
  17.  *   along with this program; if not, write to the Free Software
  18.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *   In addition, as a special exception, Michal Trojnara gives
  21.  *   permission to link the code of this program with the OpenSSL
  22.  *   library (or with modified versions of OpenSSL that use the same
  23.  *   license as OpenSSL), and distribute linked combinations including
  24.  *   the two.  You must obey the GNU General Public License in all
  25.  *   respects for all of the code used other than OpenSSL.  If you modify
  26.  *   this file, you may extend this exception to your version of the
  27.  *   file, but you are not obligated to do so.  If you do not wish to
  28.  *   do so, delete this exception statement from your version.
  29.  */
  30.  
  31. #include "common.h"
  32. #include "prototypes.h"
  33.  
  34. #ifdef USE_PTHREAD
  35.  
  36. #include <pthread.h>
  37.  
  38. static pthread_mutex_t stunnel_cs[CRIT_SECTIONS];
  39.  
  40. static pthread_mutex_t lock_cs[CRYPTO_NUM_LOCKS];
  41. static pthread_attr_t pth_attr;
  42.  
  43. void enter_critical_section(section_code i) {
  44.     pthread_mutex_lock(stunnel_cs+i);
  45. }
  46.  
  47. void leave_critical_section(section_code i) {
  48.     pthread_mutex_unlock(stunnel_cs+i);
  49. }
  50.  
  51. static void locking_callback(int mode, int type,
  52. #ifdef HAVE_OPENSSL
  53.     const /* Callback definition has been changed in openssl 0.9.3 */
  54. #endif
  55.     char *file, int line) {
  56.     if(mode&CRYPTO_LOCK)
  57.         pthread_mutex_lock(lock_cs+type);
  58.     else
  59.         pthread_mutex_unlock(lock_cs+type);
  60. }
  61.  
  62. void sthreads_init(void) {
  63.     int i;
  64.  
  65.     /* Initialize stunnel critical sections */
  66.     for(i=0; i<CRIT_SECTIONS; i++)
  67.         pthread_mutex_init(stunnel_cs+i, NULL);
  68.  
  69.     /* Initialize OpenSSL locking callback */
  70.     for(i=0; i<CRYPTO_NUM_LOCKS; i++)
  71.         pthread_mutex_init(lock_cs+i, NULL);
  72.     CRYPTO_set_id_callback(stunnel_thread_id);
  73.     CRYPTO_set_locking_callback(locking_callback);
  74.  
  75.     pthread_attr_init(&pth_attr);
  76.     pthread_attr_setdetachstate(&pth_attr, PTHREAD_CREATE_DETACHED);
  77. }
  78.  
  79. unsigned long stunnel_process_id(void) {
  80.     return (unsigned long)getpid();
  81. }
  82.  
  83. unsigned long stunnel_thread_id(void) {
  84.     return (unsigned long)pthread_self();
  85. }
  86.  
  87. int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
  88.     pthread_t thread;
  89. #ifdef HAVE_PTHREAD_SIGMASK
  90.     sigset_t newmask, oldmask;
  91.  
  92.     /* The idea is that only the main thread handles all the signals with
  93.      * posix threads.  Signals are blocked for any other thread. */
  94.     sigemptyset(&newmask);
  95.     sigaddset(&newmask, SIGCHLD);
  96.     sigaddset(&newmask, SIGTERM);
  97.     sigaddset(&newmask, SIGQUIT);
  98.     sigaddset(&newmask, SIGINT);
  99.     sigaddset(&newmask, SIGHUP);
  100.     pthread_sigmask(SIG_BLOCK, &newmask, &oldmask); /* block signals */
  101. #endif /* HAVE_PTHREAD_SIGMASK */
  102.     if(pthread_create(&thread, &pth_attr, cli, arg)) {
  103. #ifdef HAVE_PTHREAD_SIGMASK
  104.         pthread_sigmask(SIG_SETMASK, &oldmask, NULL); /* restore the mask */
  105. #endif /* HAVE_PTHREAD_SIGMASK */
  106.         if(s>=0)
  107.             closesocket(s);
  108.         return -1;
  109.     }
  110. #ifdef HAVE_PTHREAD_SIGMASK
  111.     pthread_sigmask(SIG_SETMASK, &oldmask, NULL); /* restore the mask */
  112. #endif /* HAVE_PTHREAD_SIGMASK */
  113.     return 0;
  114. }
  115.  
  116. #endif
  117.  
  118. #ifdef USE_WIN32
  119.  
  120. CRITICAL_SECTION stunnel_cs[CRIT_SECTIONS];
  121.  
  122. void enter_critical_section(section_code i) {
  123.     EnterCriticalSection(stunnel_cs+i);
  124. }
  125.  
  126. void leave_critical_section(section_code i) {
  127.     LeaveCriticalSection(stunnel_cs+i);
  128. }
  129.  
  130. void sthreads_init(void) {
  131.     int i;
  132.  
  133.     /* Initialize stunnel critical sections */
  134.     for(i=0; i<CRIT_SECTIONS; i++)
  135.         InitializeCriticalSection(stunnel_cs+i);
  136. }
  137.  
  138. unsigned long stunnel_process_id(void) {
  139.     return GetCurrentProcessId() & 0x00ffffff;
  140. }
  141.  
  142. unsigned long stunnel_thread_id(void) {
  143.     return GetCurrentThreadId() & 0x00ffffff;
  144. }
  145.  
  146. int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
  147.     DWORD iID;
  148.  
  149.     CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)cli,
  150.         arg, 0, &iID));
  151.     return 0;
  152. }
  153.  
  154. #endif
  155.  
  156. #ifdef USE_FORK
  157.  
  158. void enter_critical_section(section_code i) {
  159.     /* empty */
  160. }
  161.  
  162. void leave_critical_section(section_code i) {
  163.     /* empty */
  164. }
  165.  
  166. void sthreads_init(void) {
  167.     /* empty */
  168. }
  169.  
  170. unsigned long stunnel_process_id(void) {
  171.     return (unsigned long)getpid();
  172. }
  173.  
  174. unsigned long stunnel_thread_id(void) {
  175.     return 0L;
  176. }
  177.  
  178. static void null_handler(int sig) {
  179.     signal(SIGCHLD, null_handler);
  180. }
  181.  
  182. int create_client(int ls, int s, void *arg, void *(*cli)(void *)) {
  183.     switch(fork()) {
  184.     case -1:    /* error */
  185.         if(arg)
  186.             free(arg);
  187.         if(s>=0)
  188.             closesocket(s);
  189.         return -1;
  190.     case  0:    /* child */
  191.         if(ls>=0)
  192.             closesocket(ls);
  193.         signal(SIGCHLD, null_handler);
  194.         cli(arg);
  195.         exit(0);
  196.     default:    /* parent */
  197.         if(arg)
  198.             free(arg);
  199.         if(s>=0)
  200.             closesocket(s);
  201.     }
  202.     return 0;
  203. }
  204.  
  205. #endif
  206.  
  207. /* End of sthreads.c */
  208.